//
// File: Control.cpp
//
// Purpose: Supporting TermCtrl.dll
//

#include "stdafx.h"

// Holding Window Handle
HWND g_hWndTerminal = NULL;

// In older CE version, there's no definition for CE_THREAD_PRIO_256_NORMAL
#ifndef CE_THREAD_PRIO_256_NORMAL
#define CE_THREAD_PRIO_256_NORMAL		(THREAD_PRIORITY_NORMAL + 248)
#endif

//
// definitions extracted from "termctrl.h"
//
typedef enum {
   TW_SUCCESS = 0,         // User exitted normally (OK button)
   TW_CANCEL,              // User clicked the close 'X' (but may have typed okay)
   TW_FAILURE              // There was a failure creating the window
} TW_RET_TYPE;

TW_RET_TYPE
TerminalWindow(
   HANDLE  hCommPort,
   LPCTSTR szWindowTitle,
   HWND*   phWnd
   );

typedef TW_RET_TYPE (* PFNTERMINALWINDOW) (
   HANDLE  hCommPort,
   LPCTSTR szWindowTitle,
   HWND*   phWnd
   );

// Wrapper to load the termctrl DLL and then call TerminalWindow
// returns TRUE = OK or CANCEL, FALSE = FAILURE
BOOL
DisplayTerminalWindow(
	HANDLE hCommPort,
	TCHAR *szWindowTitle
)
{
    PFNTERMINALWINDOW pfnTerminalWindow;
    HMODULE hTermCtrl;
    BOOL bRet;

    bRet = FALSE;
    
    // Load the termctrl dll, and get the entry point
    if ((hTermCtrl = LoadLibrary(TEXT("termctrl.dll"))) == NULL) {
        DEBUGMSG(1, (TEXT("DisplayTerminalWindow *** Unable to load termctrl dll\r\n")));
        goto dtw_exit;
    }

    // OK, lets get the function pointer.
    if ((pfnTerminalWindow = (PFNTERMINALWINDOW)GetProcAddress(hTermCtrl, TEXT("TerminalWindow"))) == NULL) {
        DEBUGMSG(1, (TEXT("DisplayTerminalWindow *** GetProcAddress(TerminalWindow) failed\r\n")));
        goto dtw_exit;
    }

    //
    // Make UI run in non-realtime thread priority
    //
	int OldPriority = CeGetThreadPriority(GetCurrentThread());
    CeSetThreadPriority(GetCurrentThread(), CE_THREAD_PRIO_256_NORMAL);		// 251

    g_hWndTerminal = NULL;  // make sure handle is NULL before calling

	TW_RET_TYPE ret = pfnTerminalWindow(hCommPort, szWindowTitle, &g_hWndTerminal);
	switch (ret) {
	case TW_SUCCESS:
	case TW_CANCEL:
		bRet = TRUE;
		break;

	case TW_FAILURE:
	default:
		// bRet = FALSE
		break;
	}
    g_hWndTerminal = NULL;  // Zero Window handle now that we are done

    CeSetThreadPriority(GetCurrentThread(), OldPriority);
    
    
dtw_exit:
    if(hTermCtrl) {
        FreeLibrary(hTermCtrl);
    }
    return bRet;
    
}



//BOOL TestDevice(TCHAR *szDeviceName, DWORD dwDesiredAccess = (GENERIC_READ|GENERIC_WRITE), DWORD dwShareMode = 0 /* NO SHARE */);

BOOL TestDevice(TCHAR *szDeviceName, DWORD dwDesiredAccess, DWORD dwShareMode)
{
	HANDLE hDevice = CreateFile(szDeviceName, dwDesiredAccess, dwShareMode, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hDevice == INVALID_HANDLE_VALUE) {
		DWORD dwErr = GetLastError();

		if (ERROR_DEV_NOT_EXIST == dwErr) {
			// dwErr == 55L
			DEBUGMSG(1, (TEXT("TestDevice: Device \"%s\" Not Found.\r\n"), szDeviceName));
		}
		else {
			DEBUGMSG(1, (TEXT("TestDevice: Create Device \"%s\" Failed(%d).\r\n"), szDeviceName, dwErr));
		}

		// anyway failed.
		return FALSE;
	}
	// else, create success
	DEBUGMSG(1, (TEXT("TestDevice: Device \"%s\" Exist.\r\n"), szDeviceName));

	CloseHandle(hDevice);
	return TRUE;
}

//BOOL OpenDevice(TCHAR *szDeviceName, HANDLE &hDevice, DWORD dwDesiredAccess = (GENERIC_READ|GENERIC_WRITE), DWORD dwShareMode = 0 /* NO SHARE */);

BOOL OpenDevice(TCHAR *szDeviceName, HANDLE &hDeviceUser, DWORD dwDesiredAccess, DWORD dwShareMode)
{
	hDeviceUser = NULL;	// clean

	HANDLE hDevice = CreateFile(szDeviceName, dwDesiredAccess, dwShareMode, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hDevice == INVALID_HANDLE_VALUE) {
		DWORD dwErr = GetLastError();

		if (ERROR_DEV_NOT_EXIST == dwErr) {
			// dwErr == 55L
			DEBUGMSG(1, (TEXT("OpenDevice: Device \"%s\" Not Found.\r\n"), szDeviceName));
		}
		else {
			DEBUGMSG(1, (TEXT("OpenDevice: Create Device \"%s\" Failed(%d).\r\n"), szDeviceName, dwErr));
		}

		// anyway failed.
		return FALSE;
	}
	// else, create success
	DEBUGMSG(1, (TEXT("OpenDevice: Device \"%s\" Open.\r\n"), szDeviceName));

	hDeviceUser = hDevice;	// clean
	return TRUE;
}
